package com.example.onlinemonitoring.comCenter;

import java.text.ParseException;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import com.example.onlinemonitoring.Util.CRC16;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.HexUtil;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.model.Aschistory;
import com.example.onlinemonitoring.model.Ascsensor;
import com.example.onlinemonitoring.serviceImpl.AscsensorServiceImpl;

import lombok.Data;

import org.springframework.context.annotation.Scope;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/**
 * 主动干预消弧控制器
 */
@Service("ascCom")
@Scope("prototype")
@Data
public class AscCom extends CommPortManager {
    @Autowired
    private AscsensorServiceImpl ascserviceimpl;

    public void receiveDatas(String str) {
        str = str.toUpperCase();
        setText(str);
        String addrstr = str.substring(0, 2);
        Integer addrint = parseHex4(addrstr);
        reSend[addrindex] = 0;
        if (currcmd == 1) {
            addrindex++;
        }
        String cmdstr = str.substring(2, 4);
        Integer cmdint = parseHex4(cmdstr);
        byte[] carr = HexUtil.hexString2Bytes(str);
        Date dt = new Date();
        Ascsensor asc = new Ascsensor();
        asc.setStationid(ad.getStationid());
        asc.setDevicegroup(ad.getDevicegroup());
        asc.setDeviceaddr(addrint);
        Ascsensor record = ascserviceimpl.getModel(asc);
        asc.setLastdatatime(dt);
        switch (cmdint) {
            case 1:
                asc.setLastgrounding(carr[3] >> 0 & 1);// 接地
                asc.setLastagrounding(carr[3] >> 1 & 1);// a接地
                asc.setLastbgrounding(carr[3] >> 2 & 1);// b接地
                asc.setLastcgrounding(carr[3] >> 3 & 1);// c接地
                asc.setLastaonedisconn(carr[3] >> 4 & 1);// PT一次断线A相
                asc.setLastbonedisconn(carr[3] >> 5 & 1);// PT一次断线B相
                asc.setLastconedisconn(carr[3] >> 6 & 1);// PT一次断线C相
                asc.setLastatwodisconn(carr[3] >> 7 & 1);// PT二次断线A相

                asc.setLastbtwodisconn(carr[4] >> 0 & 1);// PT二次断线B相
                asc.setLastctwodisconn(carr[4] >> 1 & 1);// PT二次断线C相
                asc.setLastfr(carr[4] >> 2 & 1);// 铁磁谐振
                asc.setLastexception(carr[4] >> 3 & 1);// 控制器异常
                asc.setLastuooverrun(carr[4] >> 4 & 1);// Uo超限
                asc.setLastafuseblown(carr[4] >> 5 & 1);// A相熔丝熔断
                asc.setLastbfuseblown(carr[4] >> 6 & 1);// B相熔丝熔断
                asc.setLastcfuseblown(carr[4] >> 7 & 1);// C相熔丝熔断

                asc.setLastbusclose(carr[5] >> 0 & 1);// 母联闭合
                asc.setLastsystemreset(carr[5] >> 1 & 1);// 系统复归
                asc.setLastascp(carr[5] >> 2 & 1);// A相开关合位
                asc.setLastbscp(carr[5] >> 3 & 1);// B相开关合位
                asc.setLastcscp(carr[5] >> 4 & 1);// C相开关合位
                asc.setLastoverpressure(carr[5] >> 5 & 1);// 过压告警
                asc.setLastunderpressure(carr[5] >> 6 & 1);// 欠压告警
                asc.setLastlosspressure(carr[5] >> 7 & 1);// 失压告警

                asc.setLastelectrification(carr[6] >> 0 & 1);// 高压带电
                asc.setLastisolate(carr[6] >> 1 & 1);// 隔离刀闸位置
                String alm = "";
                asc.setLastalarmlevel(0);
                asc.setLastalarmmessage("");
                if (asc.getLastoverpressure() == 1) {
                    alm += "电网系统过压,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }
                if (asc.getLastunderpressure() == 1) {
                    alm += "电网系统欠压,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }
                if (asc.getLastlosspressure() == 1) {
                    alm += "电网系统失压,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }
                if (asc.getLastagrounding() == 1) {
                    alm += "消弧控制器A相接地,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }
                if (asc.getLastbgrounding() == 1) {
                    alm += "消弧控制器B相接地,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }
                if (asc.getLastcgrounding() == 1) {
                    alm += "消弧控制器C相接地,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }
                if (asc.getLastaonedisconn() == 1) {
                    alm += "消弧控制器A相PT一次断线,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }
                if (asc.getLastbonedisconn() == 1) {
                    alm += "消弧控制器B相PT一次断线,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }
                if (asc.getLastconedisconn() == 1) {
                    alm += "消弧控制器C相PT一次断线,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }
                if (asc.getLastatwodisconn() == 1) {
                    alm += "消弧控制器A相PT二次断线,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }
                if (asc.getLastbtwodisconn() == 1) {
                    alm += "消弧控制器B相PT二次断线,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }
                if (asc.getLastctwodisconn() == 1) {
                    alm += "消弧控制器C相PT二次断线,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }

                if (asc.getLastfr() == 1) {
                    alm += "消弧控制器铁磁谐振,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }
                if (asc.getLastexception() == 1) {
                    alm += "消弧控制器异常,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }
                if (asc.getLastuooverrun() == 1) {
                    alm += "消弧控制器系统不平衡超限,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }

                if (asc.getLastafuseblown() == 1) {
                    alm += "消弧控制器A相熔丝熔断,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }
                if (asc.getLastbfuseblown() == 1) {
                    alm += "消弧控制器B相熔丝熔断,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }
                if (asc.getLastcfuseblown() == 1) {
                    alm += "消弧控制器C相熔丝熔断,";
                    asc.setLastalarmlevel(2);
                    asc.setLastalarmmessage(alm);
                }
                if (alm.length() == 0) {
                    GetNormalAlarm("消弧控制器" + record.getDeviceaddr(), record.getDevicegroup(), record.getDeviceaddr(), 0,
                            record.getPointname(),
                            "", false);
                    setText("无报警");
                } else {
                    GetNormalAlarm("消弧控制器" + record.getDeviceaddr(), record.getDevicegroup(), record.getDeviceaddr(), 0,
                            record.getPointname(),
                            alm, true);
                    setText(alm);
                }
                break;
            case 3:
                asc.setLastavoltage(parseHex4(str.substring(6, 10)) * 0.1f);// A相电压
                asc.setLastbvoltage(parseHex4(str.substring(10, 14)) * 0.1f);// B相电压
                asc.setLastcvoltage(parseHex4(str.substring(14, 18)) * 0.1f);// C相电压
                asc.setLastzvoltage(parseHex4(str.substring(18, 22)) * 0.1f);// 零序电压
                asc.setLasttcurrent(parseHex4(str.substring(22, 26)) * 0.1f);// 转移电流
                asc.setLastgfrequency(parseHex4(str.substring(26, 30)) * 0.1f);// 电网频率
                setText("变压器局放设备返回数据： 站点号：1 监测点" + addrint);
                setText("A相电压" + asc.getLastavoltage());
                setText("B相电压" + asc.getLastbvoltage());
                setText("C相电压" + asc.getLastcvoltage());
                setText("零序电压" + asc.getLastzvoltage());
                setText("转移电流" + asc.getLasttcurrent());
                setText("电网频率" + asc.getLastgfrequency());
                break;
            case 5:
                controllerRet = str;
                controlCondition.signal();
                return;
            default:
                break;
        }
        asc.setLastcommunicationstatus(0);
        asc.setLasthisdatatime(addHistory(asc));
        ascserviceimpl.Update(asc, false);
    }

    private Date addHistory(Ascsensor sensor) {
        sensor = ascserviceimpl.getModel(sensor);
        if (sensor != null) {
            if (sensor.getLasthisdatatime() == null) {
                add(sensor);
                return new Date();
            } else {
                long lasttime = 0;
                long nowtime = 0;
                try {
                    lasttime = HexUtil.todate(sensor.getLasthisdatatime()).getTime();
                    nowtime = HexUtil.todate(new Date()).getTime();
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                int timersp = 60000;
                if (sensor.getLastalarmlevel() != 0) {
                    timersp = ad.getHisalarmtimersp() * 1000;
                } else {
                    timersp = ad.getHistimersp() * 1000;
                }
                if (lasttime + timersp < nowtime) {
                    add(sensor);
                    return new Date();
                }
            }
        }
        return null;
    }

    private void add(Ascsensor sensor) {
        Aschistory his = new Aschistory();
        his.setDeviceaddr(sensor.getDeviceaddr());
        his.setDevicegroup(sensor.getDevicegroup());
        his.setAbcswitch(sensor.getLastabcswitch());
        his.setAfuseblown(sensor.getLastafuseblown());
        his.setAgrounding(sensor.getLastagrounding());
        his.setAlarmlevel(sensor.getLastalarmlevel());
        his.setAlarmmessage(sensor.getLastalarmmessage());
        his.setAonedisconn(sensor.getLastaonedisconn());
        his.setAscp(sensor.getLastascp());
        his.setAtwodisconn(sensor.getLastatwodisconn());
        his.setAvoltage(sensor.getLastavoltage());
        his.setBfuseblown(sensor.getLastbfuseblown());
        his.setBgrounding(sensor.getLastbgrounding());
        his.setBonedisconn(sensor.getLastbonedisconn());
        his.setBscp(sensor.getLastbscp());
        his.setBtwodisconn(sensor.getLastbtwodisconn());
        his.setBusclose(sensor.getLastbusclose());
        his.setBvoltage(sensor.getLastbvoltage());
        his.setCfuseblown(sensor.getLastcfuseblown());
        his.setCgrounding(sensor.getLastcgrounding());
        his.setConedisconn(sensor.getLastconedisconn());
        his.setCscp(sensor.getLastcscp());
        his.setCtwodisconn(sensor.getLastctwodisconn());
        his.setCvoltage(sensor.getLastcvoltage());
        his.setDatatime(sensor.getLastdatatime());
        his.setException(sensor.getLastexception());
        his.setFr(sensor.getLastfr());
        his.setGfrequency(sensor.getLastgfrequency());
        his.setGrounding(sensor.getLastgrounding());
        his.setLosspressure(sensor.getLastlosspressure());
        his.setOverpressure(sensor.getLastoverpressure());
        his.setSystemreset(sensor.getLastsystemreset());
        his.setTcurrent(sensor.getLasttcurrent());
        his.setUnderpressure(sensor.getLastunderpressure());
        his.setUooverrun(sensor.getLastuooverrun());
        his.setZvoltage(sensor.getLastzvoltage());
        his.setPointname(sensor.getPointname());
        his.setStationid(sensor.getStationid());
        his.setIsolate(sensor.getLastisolate());
        his.setElectrification(sensor.getLastelectrification());
        ascserviceimpl.Add(his);
    }

    @Async("threadPool")
    public void startSendThread(Appdevice Appdevice) throws Exception {
        String cmd[] = new String[3];
        cmd[0] = "%s0100000025";// 遥信
        cmd[1] = "%s0300000008";// 遥测
        checkType = "crc16";
        issend.put(Thread.currentThread().getId(), true);
        String cstr = "";
        int timeoutsp = (int) Math.round(Appdevice.getTimeoutsp() * 1000);
        timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
        while (issend.get(Thread.currentThread().getId()) != null) {
            rlock.lock();
            try {
                if (isrun) {
                    if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                        addrindex = Appdevice.getAddrmin();
                    cstr = String.format(cmd[currcmd], String.format("%02X", addrindex));
                    cstr = cstr + CRC16.calcCrc16(cstr);
                    Send(cstr);
                    sendCondition.await(timeoutsp, TimeUnit.MILLISECONDS);
                    currcmd++;
                    cstr = String.format(cmd[currcmd], String.format("%02X", addrindex));
                    cstr = cstr + CRC16.calcCrc16(cstr);
                    Send(cstr);
                    sendCondition.await(timeoutsp, TimeUnit.MILLISECONDS);
                    currcmd = 0;
                    if (reSend[addrindex] > 3) {
                        ascserviceimpl.UpdateStatus(ad, addrindex, 1);
                        reSend[addrindex] = 0;
                        addrindex++;
                    }
                    reSend[addrindex]++;
                } else if (rescode != 0) {
                    setText(resmsg[rescode]);
                }
            } catch (Exception e) {
                // TODO: handle exception
            } finally {
                rlock.unlock();
            }
        }
    }
}